package task;

import statemap.FSMContext;

public class TaskFSM extends FSMContext {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public TaskFSM(Task owner) {
		super(ExecuteMap.Suspended);

		_owner = owner;
	}

	public TaskFSM(Task owner, TaskState initState) {
		super(initState);
		_owner = owner;
	}

	public void enterStartState() {
		getState().Entry(this);
		return;
	}

	public void Block() {
		_transition = "Block";
		getState().Block(this);
		_transition = "";
		return;
	}

	public void Delete() {
		_transition = "Delete";
		getState().Delete(this);
		_transition = "";
		return;
	}

	public void Done() {
		_transition = "Done";
		getState().Done(this);
		_transition = "";
		return;
	}

	public void Start() {
		_transition = "Start";
		getState().Start(this);
		_transition = "";
		return;
	}

	public void Started() {
		_transition = "Started";
		getState().Started(this);
		_transition = "";
		return;
	}

	public void Stop() {
		_transition = "Stop";
		getState().Stop(this);
		_transition = "";
		return;
	}

	public void Stopped() {
		_transition = "Stopped";
		getState().Stopped(this);
		_transition = "";
		return;
	}

	public void Suspend() {
		_transition = "Suspend";
		getState().Suspend(this);
		_transition = "";
		return;
	}

	public void Unblock() {
		_transition = "Unblock";
		getState().Unblock(this);
		_transition = "";
		return;
	}

	public TaskState getState() throws statemap.StateUndefinedException {
		if (_state == null) {
			throw (new statemap.StateUndefinedException());
		}

		return ((TaskState) _state);
	}

	protected Task getOwner() {
		return (_owner);
	}

	public void setOwner(Task owner) {
		if (owner == null) {
			throw (new NullPointerException("null owner"));
		} else {
			_owner = owner;
		}

		return;
	}

	// ---------------------------------------------------------------
	// Member data.
	//

	transient private Task _owner;

	public static abstract class TaskState extends statemap.State {
		// -----------------------------------------------------------
		// Member methods.
		//

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		protected TaskState(String name, int id) {
			super(name, id);
		}

		protected void Entry(TaskFSM context) {
		}

		protected void Exit(TaskFSM context) {
		}

		protected void Block(TaskFSM context) {
			Default(context);
		}

		protected void Delete(TaskFSM context) {
			Default(context);
		}

		protected void Done(TaskFSM context) {
			Default(context);
		}

		protected void Start(TaskFSM context) {
			Default(context);
		}

		protected void Started(TaskFSM context) {
			Default(context);
		}

		protected void Stop(TaskFSM context) {
			Default(context);
		}

		protected void Stopped(TaskFSM context) {
			Default(context);
		}

		protected void Suspend(TaskFSM context) {
			Default(context);
		}

		protected void Unblock(TaskFSM context) {
			Default(context);
		}

		protected void Default(TaskFSM context) {
			throw (new statemap.TransitionUndefinedException("State: "
					+ context.getState().getName() + ", Transition: "
					+ context.getTransition()));
		}

		// -----------------------------------------------------------
		// Member data.
		//
	}

	/* package */static abstract class ExecuteMap {
		// -----------------------------------------------------------
		// Member methods.
		//

		// -----------------------------------------------------------
		// Member data.
		//

		// -------------------------------------------------------
		// Constants.
		//
		public static final ExecuteMap_Suspended Suspended = new ExecuteMap_Suspended(
				"ExecuteMap.Suspended", 0);
		public static final ExecuteMap_Running Running = new ExecuteMap_Running(
				"ExecuteMap.Running", 1);
		public static final ExecuteMap_Blocked Blocked = new ExecuteMap_Blocked(
				"ExecuteMap.Blocked", 2);
		public static final ExecuteMap_Stopping Stopping = new ExecuteMap_Stopping(
				"ExecuteMap.Stopping", 3);
		public static final ExecuteMap_StoppedState StoppedState = new ExecuteMap_StoppedState(
				"ExecuteMap.StoppedState", 4);
		public static final ExecuteMap_Deleted Deleted = new ExecuteMap_Deleted(
				"ExecuteMap.Deleted", 5);
		private static final ExecuteMap_Default Default = new ExecuteMap_Default(
				"ExecuteMap.Default", -1);

		public static ExecuteMap_Suspended getSuspended() {
			return Suspended;
		}

		public static ExecuteMap_Running getRunning() {
			return Running;
		}

		public static ExecuteMap_Blocked getBlocked() {
			return Blocked;
		}

		public static ExecuteMap_Stopping getStopping() {
			return Stopping;
		}

		public static ExecuteMap_StoppedState getStoppedstate() {
			return StoppedState;
		}

		public static ExecuteMap_Deleted getDeleted() {
			return Deleted;
		}

		public static ExecuteMap_Default getDefault() {
			return Default;
		}

	}

	protected static class ExecuteMap_Default extends TaskState {

		private static final long serialVersionUID = 1L;

		protected ExecuteMap_Default(String name, int id) {
			super(name, id);
		}

		protected void Block(TaskFSM context) {
			Task ctxt = context.getOwner();
			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Blocked.");
				ctxt.stateUpdate("Blocked");
				ctxt.setSuspendTime();
			} finally {
				context.setState(ExecuteMap.Blocked);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void Stop(TaskFSM context) {
			Task ctxt = context.getOwner();
			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Being stopped.");
				ctxt.setTimer("Stopped", 0);
			} finally {
				context.setState(ExecuteMap.Stopping);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void Delete(TaskFSM context) {
			Task ctxt = context.getOwner();
			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Deleted.");
				ctxt.stateUpdate("Deleted");
				ctxt.updateTaskMan("Task Deleted");
			} finally {
				context.setState(ExecuteMap.Deleted);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void Start(TaskFSM context) {
			return;
		}

		protected void Started(TaskFSM context) {
			return;
		}

		protected void Suspend(TaskFSM context) {
			return;
		}

		protected void Unblock(TaskFSM context) {
			return;
		}

		protected void Done(TaskFSM context) {
			return;
		}
	}

	private static final class ExecuteMap_Suspended extends ExecuteMap_Default {

		private static final long serialVersionUID = 1L;

		private ExecuteMap_Suspended(String name, int id) {
			super(name, id);
		}

		protected void Start(TaskFSM context) {
			Task ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Running.");
				ctxt.stateUpdate("Running");
			} finally {
				context.setState(ExecuteMap.Running);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class ExecuteMap_Running extends ExecuteMap_Default {

		private static final long serialVersionUID = 1L;

		private ExecuteMap_Running(String name, int id) {
			super(name, id);
		}

		protected void Entry(TaskFSM context) {
			Task ctxt = context.getOwner();

			ctxt.setStartTime();
			ctxt.setRunTimer();
			return;
		}

		protected void Exit(TaskFSM context) {
			Task ctxt = context.getOwner();

			ctxt.setStopTime();
			ctxt.stopTimer("Done");
			return;
		}

		protected void Done(TaskFSM context) {
			Task ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Completed.");
				ctxt.stateUpdate("Done");
				ctxt.updateTaskMan("Task Done");
				ctxt.deregister();
			} finally {
				context.setState(ExecuteMap.StoppedState);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void Suspend(TaskFSM context) {
			Task ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Being suspended.");
				ctxt.stateUpdate("Suspended");
				ctxt.updateTaskMan("Task Suspended");
				ctxt.setSuspendTime();
			} finally {
				context.setState(ExecuteMap.Suspended);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class ExecuteMap_Blocked extends ExecuteMap_Default {

		private static final long serialVersionUID = 1L;

		private ExecuteMap_Blocked(String name, int id) {
			super(name, id);
		}

		protected void Block(TaskFSM context) {
			return;
		}

		protected void Unblock(TaskFSM context) {
			Task ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Unblocked.");
			} finally {
				context.setState(ExecuteMap.Suspended);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class ExecuteMap_Stopping extends ExecuteMap_Default {

		private static final long serialVersionUID = 1L;

		private ExecuteMap_Stopping(String name, int id) {
			super(name, id);
		}

		protected void Delete(TaskFSM context) {

			return;
		}

		protected void Stopped(TaskFSM context) {
			Task ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Stopped.");
				ctxt.stateUpdate("Stopped");
				ctxt.updateTaskMan("Task Stopped");
				ctxt.deregister();
			} finally {
				context.setState(ExecuteMap.StoppedState);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class ExecuteMap_StoppedState extends
			ExecuteMap_Default {

		private static final long serialVersionUID = 1L;

		private ExecuteMap_StoppedState(String name, int id) {
			super(name, id);
		}

		protected void Block(TaskFSM context) {
			return;
		}

		protected void Delete(TaskFSM context) {
			return;
		}

		protected void Stop(TaskFSM context) {
			return;
		}
	}

	private static final class ExecuteMap_Deleted extends ExecuteMap_Default {

		private static final long serialVersionUID = 1L;

		private ExecuteMap_Deleted(String name, int id) {
			super(name, id);
		}

		protected void Block(TaskFSM context) {
			return;
		}

		protected void Delete(TaskFSM context) {
			return;
		}

		protected void Start(TaskFSM context) {
			Task ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.sendMessage(3, "Running.");
				ctxt.stateUpdate("Running");
			} finally {
				context.setState(ExecuteMap.Running);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void Stop(TaskFSM context) {
			return;
		}
	}
}